<?php


namespace Hlcreation\Basic;


use Mpdf\Mpdf;
use Symfony\Component\HttpKernel\EventListener\ValidateRequestListener;
use Illuminate\Support\Facades\Config;

class WordAnalysis
{
    // 读取word文档
    public function readWord($path){
        $file = $_SERVER['DOCUMENT_ROOT']."/".$path;
        $suffix = strtolower(substr(strrchr($path, '.'), 1));
        if ($suffix == "doc") {
            $result_html = $this->comRead($file);
            $str_replace_suffix = ".doc";
        } else {
            $result_html = $this->wordParsing($file);
            $str_replace_suffix = ".docx";
        }

        $this->wordToPdf($file);
        $suffix_pdf = str_replace($str_replace_suffix, ".pdf",$file);
        $imgs = $this->pdfToPng($suffix_pdf);
        if ($imgs['code'] == 400) {
            return $imgs;
        }
        $html =   html_entity_decode(str_replace('&nbsp;','', htmlentities(trim($result_html))));
        return ['code'=>200, 'html'=>$html, 'imgs'=>$imgs['data']];
    }

    // 将word文档转为pdf
    public function wordToPdf($file){
        $p =  pathinfo($file)['dirname'];
        $command = " cd $p && soffice --headless --invisible --convert-to pdf $file";
        shell_exec($command);
        unlink($file);
    }


    // html转换为pdf
    public static function htmlToPdf($html, $pdf_path = "upload/contract/pdf/"){

        if (!strpos($html, "<html>")) {
            $html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<title></title>
	<meta name="generator" content="LibreOffice 5.3.6.1 (Linux)"/>
	<meta name="author" content="Windows &#29992;&#25143;"/>
	<meta name="changedby" content="Administrator"/>
	<meta name="changed" content="2021-05-25T10:28:23"/>
	<meta name="ICV" content="3D06AD9CB5584D5D8E89743C68A041E5"/>
	<meta name="KSOProductBuildVer" content="2052-11.1.0.10495"/>
</head><style>body{font-family: "微软雅黑"}</style><body>'.$html.'</body></html>';
        }
        // html 存放目录
//        $html = str_replace(["<p></p>", "<p>&nbsp;</p>"],"", $html);
        $file = $_SERVER['DOCUMENT_ROOT']."/".$pdf_path.Helper::getMillisecond().'.html';
        file_put_contents($file, $html);
        $p =  pathinfo($file)['dirname'];
        $command = " cd $p && soffice --headless --invisible --convert-to pdf $file";
        shell_exec($command);
        unlink($file);
        $suffix_pdf = str_replace(".html", ".pdf",$file);
        return $suffix_pdf;
    }

    // 将pdf转为图片
    public function pdfToPng($pdf){

        if (!extension_loaded('imagick')) {
            return ['code'=>400, 'msg'=>'imagick'];

        }

        if (!file_exists($pdf)) {
            return ['code'=>400, 'msg'=>'检测不到文件'];
        }

        $im = new \Imagick();

        $im->setResolution(140, 140); //设置分辨率 值越大分辨率越高

        $im->setCompressionQuality(100);

        $im->readImage($pdf);

        $p =  pathinfo($pdf)['dirname'];
        $filename =  pathinfo($pdf)['filename'];
        foreach ($im as $k => $v) {

            $v->setImageFormat('png');

            $fileName = $p . "/" . $filename ."_".$k. ".png";
            $v->thumbnailImage ( 800, 1131, true );
            if ($v->writeImage($fileName) == true) {
                $return[] = str_replace($_SERVER['DOCUMENT_ROOT']."/", Config::get('constants.host'), $fileName);
            }
        }
        unlink($pdf);
        return ['code'=>200, 'data'=>$return];
    }

    // 读取doc文件
    public function comRead($file){

        $new_html = str_replace(".doc", ".html",$file);
        if (!file_exists($new_html)) {
            $command = "PATH=/sbin:/bin:/usr/sbin:/usr/bin  unoconv -f html $file  2>&1 ";
            exec($command, $res, $rc);
            $p =  pathinfo($file)['dirname'];

            //通过复制，修改文件权限
            $bak_html = $new_html.".bak";
            copy($new_html, $bak_html);
            unlink($new_html);
            copy($bak_html, $new_html);
            unlink($bak_html);


            $html = file_get_contents($new_html);

            $html = str_replace("iso-8859-1", "utf-8", $html);
            $html = str_replace('<table', '<table border="1" ', $html);
            // 修改文件内的图片，将图片修改为base64格式
            $preg = '/<img.*?src=[\"|\']?(.*?)[\"|\']?\s.*?>/i';
            preg_match_all($preg, $html, $imgArr);
            if (count($imgArr) > 0) {
                foreach ($imgArr[1] as $img) {
                    $img_path = $p."/".$img;
                    $html = str_replace($img, Helper::imgToBase64($img_path), $html);
                    unlink($img_path);
                }
            }
            file_put_contents($new_html, $html);
        } else {
            $html = file_get_contents($new_html);
        }

        return $html;
    }
    /// 读取docx文件
    //解析word内容并返回html
    public function wordParsing($source)
    {


        //加载word文件 并 通过getSections获取word文档的全部元素
        $sections = \PhpOffice\PhpWord\IOFactory::load($source)->getSections();

        //定义html变量用于存储word文本内容
        $html = '';
        $is_analysis = false;
        //循环所有元素
        foreach($sections as $section) {

            //获取当前元素的所有子元素
            $elements = $section->getElements();
            $taleArr =[];
            //循环当前子元素

            foreach ($elements as $eky => $evl) {
                $html .= '<p>';
                if ($evl instanceof \PhpOffice\PhpWord\Element\TextRun) { //判断是否普通文本
                    $is_analysis = true;
                    $content_style = $evl->getParagraphStyle();
                    $alignment = $content_style->getAlignment();
                    $styleString = '';
                    $alignment && $styleString .= "text-align:{$alignment};";
                    $html .= '<p>';
                    $html .= sprintf('<p style="%s">', $styleString);

                    $content_elements = $evl->getElements();
                    foreach ($content_elements as $eky2 => $evl2) {
                        $html .= $this->elementHandler($evl2, $evl);
                    }
                    $html .= '</p>';

                }elseif($evl instanceof \PhpOffice\PhpWord\Element\PreserveText){ //判断是否保留元素(如自动生成链接的网址元素)

                    $is_analysis = true;
                    $data = $evl->getText();
                    $find = array('{','HYPERLINK','}',' ','"','f','g');
                    $replace = '';
                    $resText = str_replace($find, $replace, $data);
                    if(isset($resText)){
                        $html .= $resText[0];
                    }
                }
                elseif($evl instanceof \PhpOffice\PhpWord\Element\Table){
                    $is_analysis = true;
                    $all_table_elements = $evl->getRows();
                    $html .= '<table style="margin:0;padding:0;border-collapse:collapse;border-spacing:0;" >';
                    foreach ($all_table_elements as $tky => $tvl) {
                        $html .= '<tr style="padding:0">';
                        $all_table_cells = $tvl->getCells(); $addnum = 0;
                        foreach ($all_table_cells as $cky => $cvl){

                            $GridSpan = $cvl->getStyle()->getGridSpan();
                            $VMerge = $cvl->getStyle()->getVMerge(); $VMergeRows = ""; $Rowspan ="";
                            if($GridSpan) {
                                $addnum = ($GridSpan - 1 )+$addnum;
                            }
                            if ($VMerge == "restart") {
                                $new_cky = $cky + $addnum;
                                $taleArr[$new_cky] = 1;
                                $taleArr[$new_cky.'_key'] = $tky;
                                $Rowspan = "'".$taleArr[$new_cky.'_key'].$new_cky."' rowspan= '1'";

                            }
                            if ($VMerge == "continue") {
                                $new_cky = $cky + $addnum;
                                $taleArr[$new_cky]++;
                                $replace_str = "'".$taleArr[$new_cky.'_key'].$new_cky."' rowspan= '".($taleArr[$new_cky] - 1)."'";
                                $VMergeRows = "'".$taleArr[$new_cky.'_key'].$new_cky."' rowspan= '".$taleArr[$new_cky]."'";

                                $html = str_replace($replace_str, $VMergeRows, $html);
                                continue;
                            }

                            $cell_elements = $cvl->getElements();

                            //获取表格宽1111111111度(返回单位为：缇)
                            $td_width = $cvl->getWidth();
                            $td_width_px = round($cvl->getWidth()/15,0);
                            $cellStyle = $GridSpan ? "colspan= '".$GridSpan."'" : "";
                            $html .= '<td style="border: 1px solid #777777;padding:2px 5px;width:'.$td_width_px.'" '.$cellStyle." ".$Rowspan.'>';

                            foreach ($cell_elements as $cl){
                                //判断当存在elements属性时执行
                                if( property_exists($cl, 'elements') ){
                                    $content_elements = $cl->getElements();
                                    foreach ($content_elements as $eky2 => $evl2) {
                                        $html .= $this->elementHandler($evl2, $cl);
                                    }
                                }

                            }
                            $html .= '</td>';
                        }
                        $html .= '</tr>';
                    }
                    $html .= '</table>';
                }
                $html .= '</p>';


            }
            if (!$is_analysis) {
                $phpWord = \PhpOffice\PhpWord\IOFactory::load($source);
                $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML");
                $html = $xmlWriter->getContent();
            } else {
                $html = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
	<title></title>
	<meta name="generator" content="LibreOffice 5.3.6.1 (Linux)"/>
	<meta name="author" content="Windows &#29992;&#25143;"/>
	<meta name="changedby" content="Administrator"/>
	<meta name="changed" content="2021-05-25T10:28:23"/>
	<meta name="ICV" content="3D06AD9CB5584D5D8E89743C68A041E5"/>
	<meta name="KSOProductBuildVer" content="2052-11.1.0.10495"/>
</head><style>body{font-family: "微软雅黑"}</style><body>'.$html.'</body></html>';
            }
            return $html;
        }
    }

    //元素内容数据处理，$end_element最末级元素，是$parent_element的子元素；$parent_element为当前元素
    public function elementHandler($end_element, $parent_element)
    {
        $html = '';

        if ($end_element instanceof \PhpOffice\PhpWord\Element\Text) { //判断是否普通文本

            $style = $end_element->getFontStyle();
//            var_dump($style);
            //$fontFamily = mb_convert_encoding($style->getName(), 'GBK', 'UTF-8');
            $fontFamily = $style->getName();
            $fontSize = $style->getSize() ? ($style->getSize()/72)*96 : '';
            $isBold = $style->isBold();
            $fontcolor = $style->getColor();
            $underline = $style->getUnderline();
            $underline = $underline == "single" ? "underline" : $underline;
            $styleString = '';
            $fontFamily && $styleString .= "font-family:{$fontFamily};";
            $fontSize && $styleString .= "font-size:{$fontSize}px;";
            $underline && $styleString .= "text-decoration:{$underline};";
            $isBold && $styleString .= "font-weight:bold;";
            $fontcolor && $styleString .= "color:{$fontcolor};";
            $html .= sprintf('<span style="%s">%s</span>',
                $styleString,$end_element->getText()
            //mb_convert_encoding($evl2->getText(), 'GBK', 'UTF-8')
            );//dump($end_element->getText());

        }elseif ($end_element instanceof \PhpOffice\PhpWord\Element\Link) {  //判断是否链接

            $style = $end_element->getFontStyle();
            //$fontFamily = mb_convert_encoding($style->getName(), 'GBK', 'UTF-8');
            $fontFamily = $style->getName();
            $fontSize = $style->getSize() ? ($style->getSize()/72)*96 : '';
            $isBold = $style->isBold();
            $fontcolor = $style->getColor();
            $styleString = '';
            $fontFamily && $styleString .= "font-family:{$fontFamily};";
            $fontSize && $styleString .= "font-size:{$fontSize}px;";
            $isBold && $styleString .= "font-weight:bold;";
            $fontcolor && $styleString .= "color:{$fontcolor};";
            $html .= sprintf('<a href="%s" style="%s">%s</a>',
                $end_element->getSource(), $styleString, $end_element->getText()
            //mb_convert_encoding($evl2->getText(), 'GBK', 'UTF-8')
            );

        } elseif ($end_element instanceof \PhpOffice\PhpWord\Element\Image) { //判断是否图片

            //可以在这里执行自定义方法将图片上传到OSS或者图片服务器哈
            $imageDataTmp = $end_element->getImageStringData(true);
            $imageType = $end_element->getImageType() ? $end_element->getImageType() : 'image/jpg';
            $imageData = 'data:' . $imageType . ';base64,' . str_replace(array("\r\n", "\r", "\n"), "", $imageDataTmp);

            //保存文件
            //$imageSrc = './uploads/' . md5($end_element->getSource()) . '.' . $end_element->getImageExtension();
            //file_put_contents($imageSrc,base64_decode(explode(',',$imageData)[1]));

            $html .= '<img src="'. $imageData .'" style="width:100%;height:auto">';
        }
        return $html;
    }

}
